'use strict'

const Router = require('koa-router')
const rbac = require('koa-rbac')
const jwt = require('koa-jwt')
const rules = require('../middlewares/rbac-rules')
const CustomProvider = require('../middlewares/rbac-provider')
const helper = require('../utils/helper')
const User = require('../models/User')
const Customer = require('../models/Customer')
const Demand = require('../models/Demand')
const CommunicationRecord = require('../models/CommunicationRecord')
const Course = require('../models/Course')
const Class = require('../models/Class')
const Order = require('../models/Order')
const OrderStatus = require('../models/OrderStatus')
const Refundment = require('../models/Refundment')
const RefundmentStatus = require('../models/RefundmentStatus')
const FeedbackEmotion = require('../models/FeedbackEmotion')
const Feedback = require('../models/Feedback')
const Questionnaire = require('../models/Questionnaire')
const config = require('../utils/config')
const commonRecord = require('../middlewares/common-data')

const router = new Router({
  prefix: '/v1',
})

const AES_KEY = 'N2I2NmU3NGZiZTU5MWJiNGJlOTg0N2Y0'

const rbacOptions = {
  rbac: new rbac.RBAC({
    provider: new CustomProvider(rules)
  }),
  identity: function(ctx) {
    return ctx && ctx.state.user
  }
}

// router.use(jwt(config.jwt).unless({path: [/^\/\w*\/auth/]}))
router.use(jwt(config.jwt))
router.use(rbac(rbacOptions))
router.use(commonRecord)

router.get('/', rbac.allow('update'), function* () {
  this.body = {
    message: '/v1 api endpoint'
  }
})

router.get('/sources', function* () {
  this.body = this.sources
})

router.get('/types', function* () {
  this.body = this.types
})

router.get('/levels', function* () {
  this.body = this.levels
})

router.get('/demands', function* () {
  this.body = yield Demand.find({}).select({_id: 1, name: 1})
})

router.get('/managers', function* () {
  this.body = this.managers
})

router.get('/order-statuses', function* () {
  this.body = yield OrderStatus.find({}).select({_id: 1, name: 1})
})

router.get('/refundment-statuses', function* () {
  this.body = yield RefundmentStatus.find({}).select({_id: 1, name: 1})
})

router.get('/feedback-emotions', function* () {
  this.body = yield FeedbackEmotion.find({}).select({_id: 1, name: 1})
})

router.get('/register', function* () {
  const salt = helper.genRandomString(16)
  const user = new User({
    username: 'test',
    salt,
    passwordHash: helper.sha512('123456', salt),
  })
  try {
    const rs = yield user.save()
    this.body = {
      error: false,
      data: rs,
    }
  }
  catch (err) {
    this.body = {
      error: true,
    }
  }
})

router.post('/customers', function* () {
  this.checkBody('phoneNumber').len(11, 11, '电话填写有误！')
  this.checkBody('email').isEmail('邮箱填写错误！')
  if (this.errors) {
    const { errors } = this
    const errArr = errors.map((v, i) => {
      return Object.values(v)[0]
    })
    this.throw(400, {message: errArr[0]})
    return
  }
  const { body } = this.request
  const customer = new Customer(body)
  const rs = yield customer.save()
  this.body = rs
})

router.get('/customers/:_id', function* () {
  const { _id } = this.params
  const customer = yield Customer.findOne({_id})
  this.body = customer
})

router.put('/customers/:_id', function* () {
  const { _id } = this.params
  const { body } = this.request
  const rs = yield Customer.update({_id}, body)
  // "nModified": 0 | 1
  this.body = rs
})

router.delete('/customers/:_id', function* () {
  const { _id } = this.params
  const customer = yield Customer.findOne({_id})
  customer && (yield customer.remove())
  // this.status = 204
  this.body = {
    error: false,
  }
})

router.post('/customers/batch/delete', function* () {
  const { body } = this.request
  if (!body._id || body._id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Customer.find({_id: {$in: body._id}}).remove()
  this.body = rs.result
})

router.get('/customers', function* () {
  const { types, levels, sources, managers } = this
  const excluded = {
    __v: 0,
  }
  const customers = yield Customer.find({}).sort({_id: -1}).select(excluded)
  customers.forEach(v => {
    if (v.level) {
      const filteredArr = levels.filter(vv => vv._id.toString() == v.level.toString())
      if (filteredArr[0]) {
        v._doc.level = filteredArr[0]
      }
    }
    if (v.source) {
      const filteredArr = sources.filter(vv => vv._id.toString() == v.source.toString())
      if (filteredArr[0]) {
        v._doc.source = filteredArr[0]
      }
    }
    if (v.genre) {
      const filteredArr = types.filter(vv => vv._id.toString() == v.genre.toString())
      if (filteredArr[0]) {
        v._doc.genre = filteredArr[0]
      }
    }
    if (v.manager && v.manager.length > 0) {
      const filteredArr = managers.filter(vv => {
        for (let vvv of v.manager) {
          if (vvv && vvv.toString() == vv._id.toString()) {
            return true
          }
        }
      })
      v._doc.manager = filteredArr
    }
  })
  this.body = customers
})

router.post('/communication-records', function* () {
  this.checkBody('content').notEmpty('请填写内容')
  if (this.errors) {
    this.throw(400, {message: this.errors})
    return
  }
  const { body } = this.request
  const rs = yield new CommunicationRecord(body).save()
  this.body = rs
})

router.get('/communication-records', function* () {
  this.body = yield CommunicationRecord.find({}).sort({_id: -1}).select({content: 1, nextAt: 1, manager: 1})
})

router.post('/courses', function* () {
  this.checkBody('name').trim().notEmpty('请填写课程名称')
  this.checkBody('code').trim().notEmpty('请填写课程编号')
  if (this.errors) {
    this.throw(400, {message: this.errors})
    return
  }
  const { body } = this.request
  const rs = yield new Course(body).save()
  delete rs._doc.__v
  this.body = rs
})

router.put('/courses/:_id', function* () {
  const { _id } = this.params
  this.checkBody('name').trim().notEmpty('请填写课程名称')
  this.checkBody('code').trim().notEmpty('请填写课程编号')
  if (this.errors) {
    this.throw(400, {message: this.errors})
    return
  }
  const { body } = this.request
  const rs = yield Course.update({_id}, body)
  // "nModified": 0 | 1
  this.body = rs
})

router.get('/courses', function* () {
  const courses = yield Course.find({}).sort({_id: -1}).select({_id: 1, name: 1, code: 1, manager: 1, demands: 1})
  this.body = courses
})

router.delete('/courses/:_id', function* () {
  const { _id } = this.params
  const course = yield Course.findOne({_id}).remove()
  this.status = 204
})

router.post('/courses/batch/delete', function* () {
  const { body } = this.request
  if (!body._id || body._id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Course.find({_id: {$in: body._id}}).remove()
  this.body = rs.result
})

router.post('/classes', function* () {
  this.checkBody('courseCode').trim().notEmpty('请填写课程编号')
  this.checkBody('courseName').trim().notEmpty('请填写课程名称')
  if (this.errors) {
    this.throw(400, {message: this.errors})
    return
  }
  const { body } = this.request
  const rs = yield new Class(body).save()
  this.body = rs
})

router.put('/classes/:_id', function* () {
  this.checkBody('courseCode').trim().notEmpty('请填写课程编号')
  this.checkBody('courseName').trim().notEmpty('请填写课程名称')
  if (this.errors) {
    this.throw(400, {message: this.errors})
    return
  }
  const { _id } = this.params
  const { body } = this.request
  const rs = yield Class.update({_id}, body)
  this.body = rs
})

router.get('/classes', function* () {
  this.body = yield Class.find({}).sort({_id: -1}).select({_id: 1, courseCode: 1, courseName: 1, period: 1, number: 1, startAt: 1, expenses: 1, manager: 1})
})

router.delete('/classes/:_id', function* () {
  const { _id } = this.params
  const course = yield Class.findOne({_id}).remove()
  this.status = 204
})

router.post('/classes/batch/delete', function* () {
  const { body } = this.request
  if (!body._id || body._id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Class.find({_id: {$in: body._id}}).remove()
  this.body = rs.result
})

router.post('/orders', function* () {
  // TODO: validate post parameter
  const { body } = this.request
  const rs = yield new Order(body).save()
  this.body = rs
})

router.put('/orders/:_id', function* () {
  // TODO: validate
  const { _id } = this.params
  const { body } = this.request
  const rs = yield Order.update({_id}, body)
  this.body = rs
})

router.del('/orders/:_id', function* () {
  const { _id } = this.params
  const course = yield Order.findOne({_id}).remove()
  this.status = 204
})

router.post('/orders/batch/delete', function* () {
  const { body } = this.request
  if (!body._id || body._id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Order.find({_id: {$in: body._id}}).remove()
  this.body = rs.result
})

router.get('/orders', function* () {
  this.body = yield Order.find({}).sort({_id: -1})
})

router.post('/refundment', function* () {
  // TODO: validate
  const { body } = this.request
  const rs = yield new Refundment(body).save()
  this.body = rs
})

router.put('/refundment/:_id', function* () {
  // TODO: validate
  const { _id } = this.params
  const { body } = this.request
  const rs = yield Refundment.update({_id}, body)
  this.body = rs
})

router.del('/refundment/:_id', function* () {
  const { _id } = this.params
  const course = yield Refundment.findOne({_id}).remove()
  this.status = 204
})

router.post('/refundment/batch/delete', function* () {
  const { body } = this.request
  if (!body._id || body._id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Refundment.find({_id: {$in: body._id}}).remove()
  this.body = rs.result
})

router.get('/refundment', function* () {
  this.body = yield Refundment.find({}).sort({_id: -1})
})

router.post('/feedbacks', function* () {
  // TODO: validate
  const { body } = this.request
  const rs = yield new Feedback(body).save()
  this.body = rs
})

router.put('/feedbacks/:_id', function* () {
  // TODO: validate
  const { _id } = this.params
  const { body } = this.request
  const rs = yield Feedback.update({_id}, body)
  this.body = rs
})

router.del('/feedbacks/:_id', function* () {
  const { _id } = this.params
  const course = yield Feedback.findOne({_id}).remove()
  this.status = 204
})

router.post('/feedbacks/batch/delete', function* () {
  const { body: { _id } } = this.request
  if (!_id || _id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Feedback.find({_id: {$in: _id}}).remove()
  this.body = rs.result
})

router.get('/feedbacks', function* () {
  this.body = yield Feedback.find({}).sort({_id: -1}).select({_id: 1, phoneNumber: 1, content: 1, createdAt: 1, manager: 1, emotion: 1})
})

router.post('/questionnaires', function* () {
  // TODO: validate
  const { body } = this.request
  const rs = yield new Questionnaire(body).save()
  this.body = rs
})

router.put('/questionnaires/:_id', function* () {
  // TODO: validate
  const { _id } = this.params
  const { body } = this.request
  const rs = yield Questionnaire.update({_id}, body)
  this.body = rs
})

router.del('/questionnaires/:_id', function* () {
  const { _id } = this.params
  const course = yield Questionnaire.findOne({_id}).remove()
  this.status = 204
})

router.post('/questionnaires/batch/delete', function* () {
  const { body: { _id } } = this.request
  if (!_id || _id.length < 1) {
    this.throw(400, {message: '请至少选择一项！'})
    return
  }
  const rs = yield Questionnaire.find({_id: {$in: _id}}).remove()
  this.body = rs.result
})

router.get('/questionnaires', function* () {
  this.body = yield Questionnaire.find({}).sort({_id: -1}).select({_id: 1, name: 1, info: 1, manager: 1, problemList: 1})
})

// router.post('/login', async (ctx, next) => {
//   let { username, password } = ctx.request.body
//   const user = await User.findOne({username})
//   if (!user) {
//     ctx.body = {
//       error: true,
//       message: '用户名或密码错误',
//     }
//     return
//   }
//   if (helper.sha512(password, user.salt) != user.passwordHash) {
//     ctx.body = {
//       error: true,
//       message: '用户名或密码错误！',
//     }
//     return
//   }
//   ctx.body = {
//     error: false,
//     user: {
//       username: user.username,
//     },
//   }
// })

module.exports = router